package com.demo.utils;


import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;


/**
 * PDF添加水印、添加页码、合并文档、拆分PDF、删除PDF
 */
public class PDFOtherUtil {
    /**
     * PDF文件添加水印
     *
     * @param fileInputStream  源文件输入流
     * @param fileOutputStream 目标文件输出流
     * @param content          水印文本
     */
    public static void waterMark(FileInputStream fileInputStream, FileOutputStream fileOutputStream, String content) throws IOException {
        PDDocument document = PDDocument.load(fileInputStream);
        // 遍历所有页面
        for (PDPage page : document.getPages()) {
            // 获取页面的宽和高
            float width = page.getMediaBox().getWidth();
            float height = page.getMediaBox().getHeight();

            PDPageContentStream pageContentStream = new PDPageContentStream(document, page,
                    PDPageContentStream.AppendMode.APPEND, true, true);
            // 设置水印的透明度
            PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
            extendedGraphicsState.setNonStrokingAlphaConstant(0.2F);
            extendedGraphicsState.setAlphaSourceFlag(true);
            pageContentStream.setGraphicsStateParameters(extendedGraphicsState);
            // 设置水印的颜色（r,g,b）
            pageContentStream.setNonStrokingColor(new Color(100, 100, 100));
            pageContentStream.beginText();
            // 设置字体
            pageContentStream.setFont(PDType0Font.load(document, new File("src/main/resources/源柔黑体.ttf")), 20);
            // 根据纸张大小设置水印，30度倾斜
            for (int h = 100; h < height; h += 100) {
                for (int w = 20; w < width; w += 200) {
                    pageContentStream.setTextMatrix(Matrix.getRotateInstance(0.3, w, h));
                    pageContentStream.showText(content);
                }
            }
            pageContentStream.endText();
            pageContentStream.restoreGraphicsState();
            pageContentStream.close();
        }
        document.save(fileOutputStream);
    }

    /**
     * PDF添加页码
     */
    public static void pagination(FileInputStream fileInputStream, FileOutputStream fileOutputStream)
            throws IOException {
        PDDocument document = PDDocument.load(fileInputStream);
        // 总页数
        int numberOfPages = document.getNumberOfPages();
        // 遍历所有页面
        for (int i = 0; i < numberOfPages; i++) {
            PDPage page = document.getPage(i);
            float width = page.getMediaBox().getWidth();
            PDPageContentStream pageContentStream = new PDPageContentStream(document, page,
                    PDPageContentStream.AppendMode.APPEND, true, true);
            pageContentStream.beginText();
            pageContentStream.setFont(PDType0Font.load(document, new File("src/main/resources/源柔黑体.ttf")), 12);
            // 设置页码打印的位置
            pageContentStream.newLineAtOffset(width - 100, 40);
            pageContentStream.showText(String.format("第%d页/共%s页", i + 1, numberOfPages));
            pageContentStream.endText();
            pageContentStream.restoreGraphicsState();
            pageContentStream.close();
        }
        document.save(fileOutputStream);
    }

    /**
     * PDF文档合并
     */
    public static void merge(FileOutputStream fileOutputStream, FileInputStream... fileInputStreams) throws IOException {
        PDFMergerUtility mergerUtility = new PDFMergerUtility();
        // 设置目标文件
        mergerUtility.setDestinationStream(fileOutputStream);
        for (FileInputStream fileInputStream : fileInputStreams) {
            mergerUtility.addSource(fileInputStream);
        }
        mergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
    }

    /**
     * 拆分PDF
     *
     * @param fileInputStream  源文件输入流
     * @param fileOutputStream 目标文件输出流
     * @param pages            截取的页码
     */
    public static void split(FileInputStream fileInputStream, FileOutputStream fileOutputStream, int[] pages)
            throws IOException {
        try (PDDocument originDocument = PDDocument.load(fileInputStream);
             PDDocument targetDocument = new PDDocument();) {
            Arrays.sort(pages);
            for (int i = 0; i < pages.length; i++) {
                targetDocument.addPage(originDocument.getPage(pages[i] - 1));
            }
            targetDocument.save(fileOutputStream);
        }
    }

    /**
     * 删除PDF指定页面
     */
    public static void removePage(FileInputStream fileInputStream, FileOutputStream fileOutputStream, int[] pages)
            throws IOException {
        Arrays.sort(pages);
        // 因为removePage之后文档的索引就会减少，所以使用这个辅助字段
        int removedPageCount = 0;
        try (PDDocument document = PDDocument.load(fileInputStream);) {
            for (int i = 0; i < pages.length; i++) {
                document.removePage(pages[i] - 1 - removedPageCount);
                removedPageCount++;
            }
            document.save(fileOutputStream);
        }
    }
}


